package com.ciaojian.worker.config;


import com.alibaba.fastjson.JSONObject;
import com.ciaojian.core.util.LogUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Description: 捕获日志工具类
 * @Author: xiangchao
 * @Date: 2020/10/13 10:10 上午
 */
@Component
@Aspect
public class LogConfig {

    private static Logger payLog = LoggerFactory.getLogger("pay");

    @Pointcut("execution(public * com.ciaojian.worker.controller.PayController.*(..))")
    public void payPoint() {

    }

    @Before(value = "payPoint()")
    public synchronized void before(JoinPoint joinPoint) throws JsonProcessingException {

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        payLog.info(
                "****************************************************************************************************************************************************************************");
        payLog.info("请求接口={}", request.getRequestURL());
        payLog.info("请求方法={}",
                joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        String param = "";
        ObjectMapper om = new ObjectMapper();
        if (joinPoint.getArgs().length > 0) {
            for (Object o : joinPoint.getArgs()) {
                if (o instanceof HttpServletRequest || o instanceof HttpServletResponse) {
                    continue;
                }
                param = om.writeValueAsString(o);
            }
        }
        String[] headers = {"pragma", "accept", "cache-control", "host", "accept-encoding", "content-type", "connection", "content-length", "user-agent", "postman-token", "upgrade-insecure-requests", "accept-language", "charset", "origin", "referer", "sec-fetch-site", "sec-fetch-mode", "sec-fetch-user", "sec-fetch-dest", "x-forwarded-for"};
        Map<String, Object> headerMap = new LinkedHashMap<>();
        Enumeration<String> headerNames = request.getHeaderNames();
        continueOut:
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            for (String header : headers) {
                if (header.equals(name)) {
                    continue continueOut;
                }
            }
            String value = request.getHeader(name);
            headerMap.put(name, value);
        }
        payLog.info("请求header={}", om.writeValueAsString(headerMap));

        // 打印参数
        Map<String, Object> map = new LinkedHashMap<>();
        Enumeration pNames = request.getParameterNames();
        while (pNames.hasMoreElements()) {
            String name = (String) pNames.nextElement();
            String value = request.getParameter(name);
            map.put(name, value);
        }
        payLog.info("请求参数={}", "".equals(om.writeValueAsString(map)) ? "{}" : om.writeValueAsString(map));

        payLog.info("请求地址={}", request.getRemoteAddr());
        payLog.info("请求方式={}", request.getMethod());
    }

    @AfterReturning(value = "payPoint()", returning = "value")
    public synchronized void after(Object value) {
        if (value != null) {
            if (!JSONObject.toJSON(value).toString().contains("data:image/jpeg;base64")) {
                if (JSONObject.toJSON(value).toString().length() < 3000) {
                    payLog.info("响应参数={}", JSONObject.toJSON(value));
                } else {
                    payLog.info("响应参数={}", "内容过大无法显示");
                }
            }
        }
    }

    @Pointcut("execution(public * com.ciaojian.worker.controller.*.*(..))")
    public void businessPoint() {

    }

    @Before(value = "businessPoint()")
    public void businessBefore(JoinPoint joinPoint) throws JsonProcessingException {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        LogUtil.writeBusinessLog("****************************************************************************************************************************************************************************");
        LogUtil.writeBusinessLog("请求接口={}", request.getRequestURL());
        LogUtil.writeBusinessLog("请求方法={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        ObjectMapper objectMapper = new ObjectMapper();
        if (joinPoint.getArgs().length > 0) {
            for (Object o : joinPoint.getArgs()) {
                if (o instanceof HttpServletRequest || o instanceof HttpServletResponse) {
                }
            }
        }
        String[] headers = {"pragma", "accept", "cache-control", "host", "accept-encoding", "content-type", "connection", "content-length", "user-agent", "postman-token", "upgrade-insecure-requests", "accept-language", "charset", "origin", "referer", "sec-fetch-site", "sec-fetch-mode", "sec-fetch-user", "sec-fetch-dest", "x-forwarded-for"};
        Map<String, Object> headerMap = new LinkedHashMap<>();
        Enumeration<String> headerNames = request.getHeaderNames();
        continueOut:
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            for (String header : headers) {
                if (header.equals(name)) {
                    continue continueOut;
                }
            }
            String value = request.getHeader(name);
            headerMap.put(name, value);
        }
        LogUtil.writeBusinessLog("请求header={}", objectMapper.writeValueAsString(headerMap));

        // 打印参数
        Map<String, Object> map = new LinkedHashMap<>();
        Enumeration pNames = request.getParameterNames();
        while (pNames.hasMoreElements()) {
            String name = (String) pNames.nextElement();
            String value = request.getParameter(name);
            map.put(name, value);
        }
        LogUtil.writeBusinessLog("请求参数={}", "".equals(objectMapper.writeValueAsString(map)) ? "{}" : objectMapper.writeValueAsString(map));
        LogUtil.writeBusinessLog("请求地址={}", request.getRemoteAddr());
        LogUtil.writeBusinessLog("请求方式={}", request.getMethod());
    }

    @AfterReturning(value = "businessPoint()", returning = "value")
    public synchronized void businessAfter(Object value) {
        if (value != null) {
            if (!JSONObject.toJSON(value).toString().contains("data:image/jpeg;base64")) {
                if (JSONObject.toJSON(value).toString().length() < 3000) {
                    LogUtil.writeBusinessLog("响应参数={}", JSONObject.toJSON(value));
                } else {
                    LogUtil.writeBusinessLog("响应参数={}", "内容过大无法显示");
                }
            }
        }
    }
}
